Repository navigation
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
openlist-work | f2a92d9 | Nov 10 2026, 07:37 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
openlist-tsworkers | f2a92d9 | Nov 10 2026, 07:37 AM |
4 tasks done
PIKACHUIM
force-pushed
the
fix/125-kv-key-index
branch
from
November 10, 2026 07:36
c9270f6 to
f2a92d9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR 正文 — KV + DB_FORMAT=key 全局索引与并发读写
fix(store): key 格式改用全局索引,摆脱 list 配额并提速 (#125)fix/125-kv-key-indexf2a92d9Summary / 摘要
DB_FORMAT=key在 KV 上每次load/save都要用list()枚举全部键名。即使 #127 已把「逐表 list 6 次」合并成「全局 list 1 次」,Cloudflare 免费版 1000 次/天的 list 配额仍只够约 1000 次页面请求,配额耗尽后初始化与保存都会 500。本 PR 给 key 格式加一个全局索引键
openlist_key_index,并把握手式的逐条读写改成受限并发:list():索引记录当前存活的实体键名,load/save只用get/put/delete。list,读完后补写索引,无需手工操作。list,绝不当成空库。get/put改为并发 12,往返轮次从 N 降到ceil(N/12)。env_check不再为了探测而消耗 1 次list。Motivation / 背景
Issue #125 的两个层面:
kvDriver.list()在 Cloudflare 上读item.key/page.complete导致的重复翻页与配额爆炸。load/save仍要一次全局list。免费版 KV 的 list / write / delete 各 1000 次/天,一次访问就可能消耗多次;同时默认配置有 100+ 条记录,逐条串行get在边缘网络上会把单次请求拖到数秒。因此需要把「成员名单」从
list()的返回值变成可持久化的数据,并缩短读写链路。Changes / 改动内容
1. 新增索引键(
store/keycodec.ts)settings_/storages_/users_/shares_/metas_/plugins_),不会被groupKeysByTable当成实体记录,也不会被陈旧键清理误删。索引值结构:
{ "v": 1, "keys": ["metas_1", "settings_site_title", "users_1"] }只存键名,不复制记录内容;记录值仍以实体键为唯一权威。
2.
load()(store/format/key.ts)list("")1 次,分组后补写索引(best-effort,失败不影响本次读取)。list,随后重建。openlist_config、索引键或其他应用的键。3.
save()(store/format/key.ts)写入顺序刻意固定为「记录 → 索引 → 删旧键」:
load走list兜底,已写入的记录仍可见;陈旧键清理只处理已知表前缀,避免误删
openlist_config、索引键或同命名空间下其他应用的键。4. 并发读写(
runBounded)IO_CONCURRENCY = 12;list的返回顺序一致;Promise.all上千条子请求撞平台限制,也避免串行的线性延迟。5. 细粒度方法同步索引
getTable/saveTable/saveRecord/deleteRecord在索引存在时同步维护名单,避免这些路径写入/删除记录后load漏读:getTable:有索引时按前缀过滤,不回退list;saveTable:先写新记录,再替换索引中该表的键,最后删旧键;saveRecord/deleteRecord:写/删记录后同步增删索引键(索引缺失时保持缺失,由下次load重建)。6. 健康检查(
store/driver/kv.ts)get的两种签名兼容逻辑抽成kvGetText(),get()与health()共用;openlist_key_index:list(稳态读写本来也不需要);list,确保首次迁移/兜底路径可用;typeof kv.list !== "function"的能力校验(EdgeKV 无 list 时 key 格式不可用)。7. 文档
README.md与readmes/README_en.md增加 KV 配额提示:list 配额问题已在稳态解决,但每次保存仍按记录数写入,长期建议DB_DRIVER=d1或DB_FORMAT=map。配额对照
以默认配置约 118 条记录为例:
loadsaveCloudflare 免费版每天 1000 次 list / write / delete、100000 次 read:
map或d1;行为矩阵
load/save全程 0 次 listload1 次 list,随后补写索引;之后 0 次 listload走 list,数据仍可见saveTable/saveRecord/deleteRecordlistTesting / 验证
新增测试覆盖:
key format: global index replaces list() in steady state:首次 save 1 次 list,之后 load/save 均为 0 次;key format: legacy layout without index is migrated on first load:删掉索引后首次 load 回退 list 并补写,第二次 0 次 list;key format: corrupt index falls back to list and is rewritten:损坏索引不当空库,读取完整并重建;key format: stale records are deleted using the index:索引存在时保存不 list,且旧键被清理、索引同步更新;key format: records are fetched with bounded concurrency:读取确实并发且不超过 12;kv health (binding, key format) skips list when the key index exists:索引存在时健康检查 0 次 list。已知的无关失败:
npx tsx --test src/backend/server/storage_update_guangyapan.test.ts # 1 failed(addition.captcha_token undefined !== 'ct1')该失败在未应用本 PR 的干净代码上同样复现(已用
git stash验证),属 main 上预先存在的问题,与本改动无关。Compatibility / 兼容性
openlist_key_index(每次 save 1 次写);旧版本将其视为未知键,不会读取也不会删除。load多消耗 1 次 list。Known boundaries / 已知边界
map(单键读取)或d1(单查询)。d1/sql/map。/kv-get//kv-put代理读写,行为与 binding 模式一致。Checklist
tsc --noEmit通过